home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Graphics / MapMaker / Source / pointdata.c < prev    next >
Text File  |  1990-12-04  |  6KB  |  342 lines

  1. #import <stdio.h>
  2. #import <stdlib.h>
  3. #import "pointdata.h"
  4. #import "appkit/graphics.h"
  5. #import <math.h>
  6.  
  7. /* This is pointdata.c. */
  8.  
  9. void newPointList(PointList *p)
  10. {
  11.     p->head = NULL;
  12.     p->tail = NULL;
  13.     p->quantity = 0;
  14. }
  15.  
  16. void freePointList(PointList *p)
  17. {
  18.     pointNode *t;
  19.     
  20.     for(t=p->head;(t);t=p->head) {
  21.         p->head = p->head->next;
  22.         free(t);
  23.     }
  24.     p->head = NULL;
  25.     p->tail = NULL;
  26.     p->quantity = 0;
  27. }
  28.  
  29. int addBlockTo(PointList *p)
  30. {
  31.     p->tail->next = (pointNode *)malloc(sizeof(pointNode));
  32.     if (!(p->tail->next))
  33.         return 0;
  34.     p->tail = p->tail->next;
  35.     p->tail->contains = 0;
  36.     p->tail->next = NULL;
  37.     return 1;
  38. }
  39.  
  40. int addStartBlockTo(PointList *p)
  41. {
  42.     p->head = p->tail = (pointNode *)malloc(sizeof(pointNode));
  43.     if (!(p->head))
  44.         return 0;
  45.     p->head->contains = 0;
  46.     p->head->next = NULL;
  47.     return 1;
  48. }
  49.  
  50. void addPointTo(PointList *p, Point *pt)
  51. {
  52.     int r;
  53.     
  54.     /* Requires that p->tail not be full!!!!!! */
  55.     r = p->tail->contains;
  56.     p->tail->block[r].x = pt->x;
  57.     p->tail->block[r].y = pt->y;
  58.     p->tail->block[r].pen = pt->pen;
  59.     p->tail->block[r].pencolour = pt->pencolour;
  60.     p->tail->contains++;
  61. }
  62.  
  63. int addToPointList(PointList *p, Point *pt)
  64. {
  65.     if (pt->pen == SKIP)
  66.         return 1;
  67.     if (p->tail) { /* normal case */
  68.         if  (p->tail->contains >= BLOCKSIZE)
  69.             if (!(addBlockTo(p)))
  70.                 return 0;
  71.         addPointTo(p,pt);
  72.     } else { /* first point added. */
  73.         if (!(addStartBlockTo(p)))
  74.             return 0;
  75.         addPointTo(p,pt);
  76.     }
  77.     p->quantity++;
  78.     return 1;
  79. }
  80.  
  81. void eliminate(pointBlock b,int size, int index)
  82. {
  83.     int i;
  84.     for(i=index;(i<(size-1));i++)
  85.         b[i] = b[i+1];
  86. }
  87.  
  88. int removeFromPointList(PointList *p,int index)
  89. {
  90.     pointNode *s,*g;
  91.     int sum = 0;
  92.     int t = 1;
  93.     
  94.     g = NULL;
  95.     if (index >= p->quantity)
  96.         return 0;
  97.         
  98.     for(s = p->head;((s) && (t));) {
  99.         sum = sum + s->contains;
  100.         if (index < sum)
  101.             t = 0;
  102.         else {
  103.             g = s;
  104.             s=s->next;
  105.         }
  106.     }
  107.     
  108.     if (s)
  109.         if (s->contains == 1) {
  110.             if (g) {
  111.                 g->next = s->next;
  112.                 if (!(g->next))
  113.                     p->tail = g;
  114.             } else {
  115.                 p->head = s->next;
  116.                 if (!(s->next))
  117.                     p->tail = NULL;
  118.             }
  119.             free(s);
  120.         } else
  121.             eliminate(s->block,s->contains,(index - (sum - s->contains)));
  122.     else
  123.         return 0;
  124.     s->contains--;
  125.     p->quantity--;
  126.     return 1;
  127. }
  128.  
  129. void insertpointat(pointBlock b, int index, int size, Point *pt)
  130. {
  131.     int i;
  132.     
  133.     if (size >= BLOCKSIZE)
  134.         size = BLOCKSIZE -1;
  135.     for(i = size;(i>index);i--)
  136.         b[i] = b[i-1];
  137.     b[index] = *pt;
  138. }
  139.  
  140. int insertInPointListAt(PointList *p,Point *pt, int index)
  141. {
  142.     pointNode *s, *g;
  143.     int sum = 0;
  144.     int t = 1;
  145.     int base;
  146.     
  147.     if (pt->pen == SKIP)
  148.         return 1;
  149.     if (index > p->quantity)
  150.         return 0;
  151.     if (index == p->quantity)
  152.         return addToPointList(p,pt);
  153.         
  154.     for(s = p->head;(t);) {
  155.         sum = sum + s->contains;
  156.         if (index < sum)
  157.             t = 0;
  158.         else {
  159.             g = s;
  160.             s= s->next;
  161.         }
  162.     }
  163.     
  164.     if (s) {
  165.         base = sum - s->contains;
  166.         if (s->contains == BLOCKSIZE) { /* can't insert to s->block (cause it's full.) */
  167.             if (s->next) { /* another node exists */
  168.                 if (s->next->contains == BLOCKSIZE)  {/* can't do next node either. */
  169.                     /* so we insert a node. */
  170.                     g = s->next;
  171.                     s->next = (pointNode *)malloc(sizeof(pointNode));
  172.                     if (!(s->next))
  173.                          return 0;
  174.                     s->next->block[0] = s->block[(BLOCKSIZE-1)];
  175.                     s->next->next = g;
  176.                     s->next->contains = 1;
  177.                     insertpointat(s->block,(index-base),(s->contains),pt);
  178.                 } else {
  179.                     insertpointat(s->next->block,0,s->next->contains,&(s->block[BLOCKSIZE-1]));
  180.                     insertpointat(s->block,(index-base),s->contains,pt);
  181.                     (s->next->contains)++;
  182.                 }
  183.             } else { /* s is full, s is tail. */
  184.                 g = (pointNode *)malloc(sizeof(pointNode));
  185.                 if (!(g))
  186.                     return 0;
  187.                 g->block[0] = s->block[(BLOCKSIZE-1)];
  188.                 g->contains = 1;
  189.                 g->next = NULL;
  190.                 s->next = g;
  191.                 p->tail = g;
  192.                 insertpointat(s->block,(index-base),s->contains,pt);
  193.             }
  194.         } else { /* ok to insert to s->block. */
  195.             insertpointat(s->block,(index-base),s->contains,pt);
  196.             (s->contains)++;
  197.         }
  198.     } else
  199.         return 0;
  200.     p->quantity++;
  201.     return 1;
  202. }
  203.  
  204. int gotoPointInList(PointList *p,int index,Point **pt)
  205. {
  206.     int total = 0;
  207.     pointNode *n;
  208.     int t=1;
  209.     int base;
  210.     
  211.     if ((index >= p->quantity) || (index <0))
  212.         return 0;
  213.     
  214.     for(n=p->head;(t);) {
  215.         total = total + n->contains;
  216.         if (total > index)
  217.             t = 0;
  218.         else
  219.             n = n->next;
  220.     }
  221.     base = total - n->contains;
  222.  
  223.     *pt = &(n->block[(index-base)]);
  224.     p->curr = n;
  225.     p->currpos = (index-base);
  226.     p->currtot = index;
  227.     return 1;
  228. }
  229.  
  230. int gotoNextPointInList(PointList *p, Point **pt)
  231. {
  232.     if (p->currtot >= (p->quantity-1))
  233.         return 0;
  234.     if ((p->currpos+1) == p->curr->contains) {
  235.         p->curr = p->curr->next;
  236.         if (!(p->curr))
  237.             return 0;
  238.         else {
  239.             p->currpos = 0;
  240.             *pt = &(p->curr->block[0]);
  241.         }
  242.     } else {
  243.         if (!(p->curr))
  244.             return 0;
  245.         *pt = &(p->curr->block[++(p->currpos)]);
  246.     }
  247.     p->currtot++;
  248.     return 1;
  249. }
  250.  
  251. int lastPointInList(PointList *p, Point **pt)
  252. {
  253.     if (p->quantity == 0)
  254.         return 0;
  255.     *pt = &(p->tail->block[p->tail->contains-1]);
  256.     return 1;
  257. }
  258.  
  259. void doTestShape(PointList *p)
  260. {
  261.     Point pt;
  262.     pt.pencolour = NX_BLACK;
  263.     pt.pen = DOWN;
  264.     
  265.     pt.x = 0.3;
  266.     pt.y = 0.3;
  267.     addToPointList(p,&pt);
  268.     pt.x = -0.3;
  269.     addToPointList(p,&pt);
  270.     pt.y = -0.3;
  271.     addToPointList(p,&pt);
  272.     pt.x = 0.3;
  273.     addToPointList(p,&pt);
  274.     pt.y = -0.1;
  275.     addToPointList(p,&pt);
  276.     pt.x = 0.1;
  277.     pt.pen = UP;
  278.     addToPointList(p,&pt);
  279. }
  280.  
  281. int savePointList(PointList *p,char *fn)
  282. {
  283.     FILE *fp;
  284.     int t;
  285.     Point *pt;
  286.     
  287.     /* attempt to write the PointList. */
  288.     fp = fopen(fn,"w");
  289.     if (fp) {
  290.         for(t=gotoPointInList(p,0,&pt);t;t=gotoNextPointInList(p,&pt))
  291.             fprintf(fp,"%f %f %d %f\n",pt->x,pt->y,pt->pen,pt->pencolour);
  292.         fclose(fp);
  293.         return 1;
  294.     } else
  295.         return 0;
  296. }
  297.  
  298. int loadPointList(PointList *p,char *fn)
  299. {
  300.     FILE *fp;
  301.     Point pt;
  302.     int t;
  303.     
  304.     fp = fopen(fn,"r");
  305.     if (fp) {
  306.         for(t = fscanf(fp,"%f %f %d %f\n",&(pt.x),&(pt.y),&(pt.pen),&(pt.pencolour)); (t == 4);
  307.             t = fscanf(fp,"%f %f %d %f\n",&(pt.x),&(pt.y),&(pt.pen),&(pt.pencolour)))
  308.             addToPointList(p,&pt);
  309.         fclose(fp);
  310.         return 1;
  311.     } else
  312.         return 0;
  313. }
  314.  
  315. int nearestPointInList(PointList *p,Point **pt,float x,float y,int *index)
  316. {
  317.     int s;
  318.     Point *pt2;
  319.     float dist,mindist;
  320.     int counter;
  321.     
  322.     if (p->quantity == 0)
  323.         return 0;
  324.     counter = 0;
  325.     s = gotoPointInList(p,0,&pt2);
  326.     mindist = ((x - pt2->x) * (x - pt2->x)) + ((y - pt2->y) * (y - pt2->y));
  327.     *pt = pt2;
  328.     *index = counter;
  329.     for(s=gotoNextPointInList(p,&pt2);s;s=gotoNextPointInList(p,&pt2)) {
  330.         counter++;
  331.         dist = (((x - pt2->x) * (x - pt2->x)) + ((y - pt2->y) * (y - pt2->y)));
  332.         if (dist < mindist) {
  333.             *pt = pt2;
  334.             *index = counter;
  335.             mindist = dist;
  336.         }
  337.     }
  338.     return 1;
  339. }
  340.  
  341.     
  342.